package com.filex.ads.network;

import android.content.Context;
import android.os.Build;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.webkit.WebSettings;
import android.webkit.WebView;

import com.filex.ads.common.GpsHelper;
import com.filex.ads.common.logging.Logger;
import com.filex.ads.volley.toolbox.HurlStack;
import com.filex.ads.common.Constants;
import com.filex.ads.common.Preconditions;
import com.filex.ads.common.utils.DeviceUtils;
import com.filex.ads.volley.Cache;
import com.filex.ads.volley.Network;
import com.filex.ads.volley.toolbox.BasicNetwork;
import com.filex.ads.volley.toolbox.DiskBasedCache;

import java.io.File;

import javax.net.ssl.SSLSocketFactory;

public class Networking {
    static final String CACHE_DIRECTORY_NAME = "filex-volley-cache";
    private static final String DEFAULT_USER_AGENT = System.getProperty("http.agent");

    private volatile static FilexRequestQueue sRequestQueue;
    private volatile static String sUserAgent;
    private static boolean sUseHttps = false;
    private static Context mContext;
    private static GpsHelper.AdvertisingInfo sAdvertisingInfo;

    public static void initialize(Context context) {
        mContext = context.getApplicationContext();
        fetchAdvertisingInfoAsync();
    }

    private static void fetchAdvertisingInfoAsync() {
        GpsHelper.fetchAdvertisingInfoAsync(mContext, new GpsHelper.GpsHelperListener() {
            @Override
            public void onFetchAdInfoCompleted(GpsHelper.AdvertisingInfo advertisingInfo) {
                sAdvertisingInfo = advertisingInfo;
            }

            @Override
            public void onFetchAdInfoFailed(String info) {
                Logger.e("onFetchAdInfoFailed:" + info);
            }
        });
    }

    @NonNull
    public static FilexRequestQueue getRequestQueue(@NonNull final Context context) {
        FilexRequestQueue requestQueue = sRequestQueue;
        // Double-check locking to initialize.
        if (requestQueue == null) {
            synchronized (Networking.class) {
                requestQueue = sRequestQueue;
                if (requestQueue == null) {

                    final SSLSocketFactory socketFactory = CustomSSLSocketFactory.getDefault(Constants.TEN_SECONDS_MILLIS);

                    final HurlStack httpStack = new HurlStack(null, socketFactory);

                    final Network network = new BasicNetwork(httpStack);
                    final File volleyCacheDir = new File(context.getCacheDir().getPath() +
                            File.separator + CACHE_DIRECTORY_NAME);
                    final Cache cache = new DiskBasedCache(volleyCacheDir,
                            (int) DeviceUtils.diskCacheSizeBytes(volleyCacheDir, Constants.TEN_MB));
                    requestQueue = new FilexRequestQueue(cache, network);
                    sRequestQueue = requestQueue;
                    requestQueue.start();
                }
            }
        }

        return requestQueue;
    }


    /**
     * Caches and returns the WebView user agent to be used across all SDK requests. This is
     * important because advertisers expect the same user agent across all request, impression, and
     * click events.
     */
    @NonNull
    public static String getUserAgent(@NonNull Context context) {
        Preconditions.checkNotNull(context);

        String userAgent = sUserAgent;
        if (userAgent == null) {
            synchronized (Networking.class) {
                userAgent = sUserAgent;
                if (userAgent == null) {
                    try {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                            userAgent = WebSettings.getDefaultUserAgent(context);
                        } else if (Looper.myLooper() == Looper.getMainLooper()) {
                            // WebViews may only be instantiated on the UI thread. If anything goes
                            // wrong with getting a user agent, use the system-specific user agent.
                            userAgent = new WebView(context).getSettings().getUserAgentString();
                        } else {
                            userAgent = DEFAULT_USER_AGENT;
                        }
                    } catch (Exception e) {
                        // Some custom ROMs may fail to get a user agent. If that happens, return
                        // the Android system user agent.
                        userAgent = DEFAULT_USER_AGENT;
                    }
                    sUserAgent = userAgent;
                }
            }
        }

        return userAgent;
    }

    /**
     * Gets the previously cached WebView user agent. This returns the default userAgent if the
     * WebView user agent has not been initialized yet.
     *
     * @return Best-effort String WebView user agent.
     */
    @NonNull
    public static String getCachedUserAgent() {
        final String userAgent = sUserAgent;
        if (userAgent == null) {
            return DEFAULT_USER_AGENT;
        }
        return userAgent;
    }

    public static GpsHelper.AdvertisingInfo getAdvertisingInfo() {
        return sAdvertisingInfo;
    }

    /**
     * Set whether to use HTTP or HTTPS for WebView base urls.
     */
    public static void useHttps(boolean useHttps) {
        sUseHttps = useHttps;
    }

    public static boolean shouldUseHttps() {
        return sUseHttps;
    }

    public static String getScheme() {
        return Constants.HTTP;
    }

    public static String getBaseUrlScheme() {
        return shouldUseHttps() ? Constants.HTTPS : Constants.HTTP;
    }

}
